﻿#region Copyright(C) 2018 FI Ltd. All rights reserved.
// ==================================================================================================
// Copyright(C) 2018 FI Ltd. All rights reserved.
//
// SYSTEM NAME	    : FI.Net Application Framework
// COMPONENT ID	    : FI.Core
// COMPONENT DESC   : FI.Net Core Foundation
//
// CREATED DATE/BY  : 18 Aug 2018 / Tian Mi
//
// REVISION HISTORY :	
// DATE/BY			SR#/CS/PM#/OTHERS		DESCRIPTION OF CHANGE
// ==================================================================================================
#endregion

using System;
using System.Collections.Generic;
using System.Linq;
using FI.Core.Properties;
using FI.Core.Utilities;

namespace FI.Core
{
    /// <summary>
    /// This represent a collection of <see cref="LocalizableText"/>.
    /// </summary>
    public class LocalizableTextCollection:List<LocalizableText>
    {
        #region Fields
        private const string Key4NeutralEntry = "";
        #endregion

        #region Public Methods

        /// <summary>
        /// Adds the specified entry.
        /// </summary>
        /// <param name="entry">The entry.</param>
        public new void Add(LocalizableText entry)
        {
            Guard.ArgumentNotNull(entry, "entry");
            if (entry.IsCultureNeutral)
            {
                this.AddNeutralText(entry.Text);
            }
            else
            {
                this.AddText(entry.Culture, entry.Text);
            }
        }

        /// <summary>
        /// Adds the text.
        /// </summary>
        /// <param name="culture">The culture.</param>
        /// <param name="text">The text.</param>
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1307:SpecifyStringComparison", MessageId = "System.String.Compare(System.String,System.String,System.Boolean)"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1304:SpecifyCultureInfo", MessageId = "System.String.Compare(System.String,System.String,System.Boolean)")]
        public void AddText(string culture, string text)
        {
            Guard.ArgumentNotNullOrEmpty(culture, "culture");
            Guard.ArgumentNotNullOrEmpty(text, "text");
            if (this.Any(item=> string.Compare(culture,item.Culture, true) == 0))
            {
                throw new ArgumentException(Resources.ExceptionDuplicateCulture.Format(new object[] { culture }), "culture");
            }
            base.Add(new LocalizableText(culture, text));
        }

        /// <summary>
        /// Adds the neutral text.
        /// </summary>
        /// <param name="text">The text.</param>
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1307:SpecifyStringComparison", MessageId = "System.String.Compare(System.String,System.String,System.Boolean)"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1304:SpecifyCultureInfo", MessageId = "System.String.Compare(System.String,System.String,System.Boolean)")]
        public void AddNeutralText(string text)
        {
            Guard.ArgumentNotNullOrEmpty(text, "text");
            if (this.Any(item => string.Compare(Key4NeutralEntry, item.Culture, true) == 0))
            {
                throw new InvalidOperationException(Resources.ExceptionDuplicateNeutralEntry);
            }
            base.Add(new LocalizableText(Key4NeutralEntry, text));
        }

        /// <summary>
        /// Removes the entry.
        /// </summary>
        /// <param name="culture">The culture.</param>
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1307:SpecifyStringComparison", MessageId = "System.String.Compare(System.String,System.String,System.Boolean)"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1304:SpecifyCultureInfo", MessageId = "System.String.Compare(System.String,System.String,System.Boolean)")]
        public void RemoveEntry(string culture)
        {
            Guard.ArgumentNotNullOrEmpty(culture, "culture");
            LocalizableText entry = this.FirstOrDefault(item => string.Compare(culture, item.Culture, true) == 0);
            if (null == entry)
            {
                throw new ArgumentException(Resources.ExceptionCultureNotExists.Format(new object[] { culture }), "culture");
            }
            base.Remove(entry);
        }

        /// <summary>
        /// Removes the neutral entry.
        /// </summary>
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1307:SpecifyStringComparison", MessageId = "System.String.Compare(System.String,System.String)")]
        public void RemoveNeutralEntry()
        {
            LocalizableText entry = this.FirstOrDefault(item => string.Compare(Key4NeutralEntry, item.Culture) == 0);
            if (null == entry)
            {
                throw new KeyNotFoundException(Resources.ExceptionNeutralEntryNotExists);
            }
            base.Remove(entry);
        }


        /// <summary>
        /// Try to get the <see cref="LocalizableText"/> based on the specified culture.
        /// </summary>
        /// <param name="culture">The culture.</param>
        /// <param name="fallbackToNeutral">if set to <c>true</c> [fallback to neutral].</param>
        /// <param name="entry">The <see cref="LocalizableText"/> found.</param>
        /// <returns>A <see cref="bool"/> value indicating the <see cref="LocalizableText"/> with the specified culture is found.</returns>
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1307:SpecifyStringComparison", MessageId = "System.String.Compare(System.String,System.String,System.Boolean)"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1304:SpecifyCultureInfo", MessageId = "System.String.Compare(System.String,System.String,System.Boolean)"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1307:SpecifyStringComparison", MessageId = "System.String.Compare(System.String,System.String)")]
        public bool TryGetEntry(string culture, bool fallbackToNeutral , out LocalizableText entry)
        {
            Guard.ArgumentNotNullOrEmpty(culture, "culture");
            entry = this.FirstOrDefault(item => string.Compare(culture, item.Culture,true) == 0);
             if(null != entry)
             {
                 return true;
             }

             if (culture.Length > 2)
             {
                 culture = culture.Substring(0, 2);
                 entry = this.FirstOrDefault(item => string.Compare(culture, item.Culture) == 0);
                 if (null != entry)
                 {
                     return true;
                 }
             }

             if (fallbackToNeutral)
             {
                 entry = this.FirstOrDefault(item => string.Compare(Key4NeutralEntry, item.Culture) == 0);
                 if (null != entry)
                 {
                     return true;
                 }
             }
             return false;
        }

        /// <summary>
        /// Try to get the culture nuetral <see cref="LocalizableText"/>.
        /// </summary>
        /// <param name="entry">The culture neutral <see cref="LocalizableText"/>.</param>
        /// <returns>A <see cref="bool"/> value indicating the neutral <see cref="LocalizableText"/> is found.</returns>
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1307:SpecifyStringComparison", MessageId = "System.String.Compare(System.String,System.String)")]
        public bool TryGetNeutralEntry(out LocalizableText entry)
        {
            entry = this.FirstOrDefault(item => string.Compare(Key4NeutralEntry, item.Culture) == 0);
            return entry != null;
        }
        
        #endregion
    }
}
